import { SetupContext, ref, watch } from "vue";
import { ListViewProps } from "../list-view.props";
import { UseDataView } from "./types";

export function useDataView(props: ListViewProps, context: SetupContext): UseDataView {
    const identifyField = ref(props.idField);
    const originalData = ref(props.data);
    const rawView = ref(props.data);
    const keepOrder = ref(props.keepOrder);

    function resetDataView() {
        const dataViewItems = originalData.value.map((origin: any, index: number) => {
            if (typeof origin !== 'object') {
                return { __fv_index__: index, name: origin };
            }
            origin.__fv_index__ = index;
            return origin;
        });
        rawView.value = dataViewItems;
        return dataViewItems;
    }
    const dataView = ref(resetDataView());

    watch(
        () => props.data,
        (newData: any[]) => {
            if (keepOrder.value) {
                const newDataMap = newData.reduce<Map<string, boolean>>((result: Map<string, boolean>, newDataItem: any) => {
                    result.set(newDataItem.id, true);
                    return result;
                }, new Map<string, boolean>());
                const originalDataMap = originalData.value.reduce<Map<string, boolean>>((result: Map<string, boolean>, dataItem: any) => {
                    result.set(dataItem.id, true);
                    return result;
                }, new Map<string, boolean>());
                const mergedData = dataView.value.filter((dataItem: any) => newDataMap.has(dataItem.id));
                const dataToAdd = newData.filter((dataItem: any) => !originalDataMap.has(dataItem.id));
                originalData.value = [...mergedData, ...dataToAdd];
            } else {
                originalData.value = newData;
            }
            dataView.value = resetDataView();
        }
    );

    function getSelectionItems(selectionValues: string[]): any[] {
        const selectionItems = selectionValues.map((selectionValue: string) => {
            const selectionItemIndex = rawView.value.findIndex((rawViewItem: any) => rawViewItem[identifyField.value] === selectionValue);
            if (selectionItemIndex > -1) {
                return rawView.value[selectionItemIndex];
            }
            return null;
        });
        return selectionItems.filter((item: any) => item != null);
    }

    return {
        dataView,
        getSelectionItems
    };
}
